home *** CD-ROM | disk | FTP | other *** search
/ Utilities Professional 1-1500 / Utilities Professional 1-1500 (1994)(WPD)[!].iso / 12511500 / var1481.dms / var1481.adf / Extract_Me.LHA / misc / t2a2.c < prev    next >
C/C++ Source or Header  |  1994-07-07  |  23KB  |  873 lines

  1. /***********************************************************
  2. *
  3. *    This file is Copyright © 1990-1994 Dan Wesnor
  4. *
  5. *    This file and any executables resulting from compilation
  6. *    of this file are freely distributable so long as the
  7. *    above copyright statement is included intact.  This
  8. *    statement of distributability is limited to this file
  9. *    only, and does not include any other file in this
  10. *    archive.
  11. *
  12. *    No gaurantees of usability are made for this file or
  13. *    any executables generated from it.  Use at your own risk.
  14. *
  15. ************************************************************
  16. *
  17. *    This program generates an MC script from a 3DDD object
  18. *    file as generated by Impulse's renderers (Turbo Silver
  19. *    and Imagine).  This version show how to generate objects
  20. *    using vertex based definitions of triangles.
  21. *
  22. *    The 3DDD parser is not all that great, and could be
  23. *    improved upon.  Someone could also use this code as
  24. *    a basis for a program which generates scripts from other 
  25. *    object formats as well.
  26. *
  27. *    NOTE: be careful using this code on machines with
  28. *    int lengths other than 32 bits!
  29. *
  30. ***********************************************************/
  31.  
  32. #include "turbo.h"
  33. #include <fcntl.h>
  34. #include <stdio.h>
  35. #include <math.h>
  36. #include <stdlib.h>
  37.  
  38. #ifndef max
  39. #define max(a,b)    (((a)>(b))?(a):(b))
  40. #endif
  41. #ifndef min
  42. #define min(a,b)    (((a)<(b))?(a):(b))
  43. #endif
  44.  
  45. typedef struct {
  46.     unsigned int    form,
  47.                     size,
  48.                     type;
  49. } Form, *FormPtr;
  50.  
  51. #define MakeName(s)    (((s)[0]<<24)+((s)[1]<<16)+((s)[2]<<8)+(s)[3])
  52.  
  53. typedef struct {
  54.     unsigned int    name,
  55.                     len;
  56. } Chunk, *ChunkPtr;
  57.  
  58. #define ReadData(f,b,s)    read((f),(b),(s)+((s)%2))    /* force a read of even bytes */
  59.  
  60.  
  61. typedef struct str_surface {
  62.     struct str_surface    *next;
  63.     int                    num;
  64.     COLOR                colr,
  65.                         refl,
  66.                         tran;
  67.     UBYTE                hard,
  68.                         spec,
  69.                         index;
  70.     char                name[32];
  71. } Surface, *SurfacePtr;
  72.     
  73.  
  74. #define QUIET        0x0
  75. #define TERSE        0x1
  76. #define VERBOSE        0x2
  77.  
  78.  
  79. #define FND_PNTS    0x1
  80. #define FND_POSI    0x2
  81. #define FND_NAME    0x4
  82. #define FND_SHAP    0x8
  83. #define FND_AXIS    0x10
  84. #define FND_SIZE    0x20
  85. #define FND_EDGE    0x40
  86. #define FND_FACE    0x80
  87. #define FND_COLR    0x100
  88. #define FND_REFL    0x200
  89. #define FND_TRAN    0x400
  90. #define FND_CLST    0x800
  91. #define FND_SPEC    0x1000
  92. #define FND_TLST    0x2000
  93. #define FND_RLST    0x4000
  94. #define FND_MTTR    0x8000
  95. #define FND_INTS    0x10000
  96. #define FND_PRP0    0x20000
  97. #define FND_SPC1    0x40000
  98. #define FND_PRP1    0x80000
  99.  
  100.  
  101. FILE *ofh=0;
  102. char *filename;
  103. unsigned char printmode = TERSE;
  104. long flags=0;
  105.  
  106. #define FL_OBJECTS    0x1
  107.  
  108. #define CHECKTERSE     if (printmode >= TERSE)
  109. #define CHECKVERBOSE    if (printmode >= VERBOSE)
  110.  
  111. float scalefactor=1.0;
  112.  
  113.  
  114. SurfacePtr surfList=NULL;
  115.  
  116. SurfacePtr MakeSurface(UBYTE cr, UBYTE cg, UBYTE cb, UBYTE rr, UBYTE rg, UBYTE rb, UBYTE tr, UBYTE tg, UBYTE tb, UBYTE h, UBYTE s, UBYTE i)
  117. {
  118.     SurfacePtr    surf;
  119.     
  120.     surf = surfList;
  121.     
  122.     while (surf) 
  123.     {
  124.         if ((surf->colr[0] == cr) && (surf->colr[1] == cg) && (surf->colr[2] == cb)
  125.                 && (surf->refl[0] == rr) && (surf->refl[1] == rg) 
  126.                 && (surf->refl[2] == rb)
  127.                 && (surf->tran[0] == tr) && (surf->tran[1] == tg) 
  128.                 && (surf->tran[2] == tb)
  129.                 && (surf->hard == h) && (surf->spec == s) 
  130.                 && (surf->index == i))
  131.             return surf;
  132.         surf = surf->next;
  133.     }
  134.  
  135.     if (!(surf = (SurfacePtr)calloc(1, sizeof(Surface)))) 
  136.     {
  137.         fprintf(stdout, "Cannot allocate new color\n");
  138.         return surfList;
  139.     }
  140.     
  141.     surf->num = surfList ? surfList->num+1 : 0;
  142.     surf->next = surfList;
  143.     surfList = surf;
  144.     surf->colr[0] = cr;
  145.     surf->colr[1] = cg;
  146.     surf->colr[2] = cb;
  147.     surf->refl[0] = rr;
  148.     surf->refl[1] = rg;
  149.     surf->refl[2] = rb;
  150.     surf->tran[0] = tr;
  151.     surf->tran[1] = tg;
  152.     surf->tran[2] = tb;
  153.     surf->hard = h;
  154.     surf->spec = s;
  155.     surf->index = i;
  156.     sprintf(surf->name, "T2AS_%s_%d", filename, surf->num);
  157.     
  158.     fprintf(ofh, "color %s {\n", surf->name);
  159.     fprintf(ofh, "\tdiff\t<%f, %f, %f>\n", cr/255.0, cg/255.0, cb/255.0);
  160.     if (tr && tg && tb)
  161.         fprintf(ofh, "\ttrans\t<%f, %f, %f>\n", tr/255.0, tg/255.0, tb/255.0);
  162.     if (rr && rg && rb)
  163.         fprintf(ofh, "\trefl\t<%f, %f, %f>\n", rr/255.0, rg/255.0, rb/255.0);
  164.     if (s) 
  165.     {
  166.         fprintf(ofh, "\tpcoef\t%f\n", h/5.0);
  167.         fprintf(ofh, "\tprefl\t%f\n", s/255.0);
  168.     }
  169.     if (i)
  170.         fprintf(ofh, "\tindex\t%f\n", i/100.0+1.0);
  171.     fprintf(ofh, "}\n\n");
  172.  
  173.     return surf;
  174. }
  175.  
  176.  
  177.  
  178. float imn[3]={1e6, 1e6, 1e6}, imx[3]={-1e6, -1e6, -1e6};
  179.  
  180. void GetDescChunk(int ifd, int len)
  181. {
  182.     Chunk        chunk;
  183.     int            whatami=0;
  184.     int            found=0;
  185.     int            i, p1, p2, p3;
  186.     int            degen;
  187.     SurfacePtr    surf;
  188.     PNTS         *pnts;
  189.     POSI         posi;
  190.     NAME         name;
  191.     SHAP         shap;
  192.     AXIS         axis;
  193.     SIZE         size;
  194.     EDGE         *edge;
  195.     FACE         *face;
  196.     COLR         colr;
  197.     REFL         refl;
  198.     TRAN         tran;
  199.     SPC1        spc1;
  200.     CLST         *clst;
  201.     SPEC         spec;
  202.     TLST         *tlst;
  203.     RLST         *rlst;
  204.     MTTR         mttr;
  205.     INTS         ints;
  206.     PRP0         prp;
  207.     PRP1         prp1;
  208.     
  209.     colr.col[0] = colr.col[1] = colr.col[2] = 255;
  210.     refl.col[0] = refl.col[1] = refl.col[2] = 0;
  211.     tran.col[0] = tran.col[1] = tran.col[2] = 0;
  212.  
  213.     while (len) 
  214.     {
  215.         len -= read(ifd, &chunk, sizeof(Chunk));
  216.         chunk.len += chunk.len % 2;
  217.  
  218.         if (chunk.name == MakeName("NAME")) 
  219.         {
  220.             len -= ReadData(ifd, &name, sizeof(NAME));
  221.             CHECKVERBOSE { fprintf(stdout, "\t\tNAME:  %s\n", name.Name); }
  222.         }
  223.  
  224.         else if (chunk.name == MakeName("SHAP")) 
  225.         {
  226.             len -= ReadData(ifd, &shap, sizeof(SHAP));
  227.             CHECKVERBOSE { fprintf(stdout, "\t\tSHAP:  "); }
  228.             switch (shap.Lamp) 
  229.             {
  230.                 case LMP_NOTALAMP:
  231.                     whatami = shap.Shape;
  232.                     switch (shap.Shape) 
  233.                     {
  234.                         case SHP_SPHERE:
  235.                             CHECKVERBOSE { fprintf(stdout, "sphere\n"); }
  236.                             break;
  237.                 
  238.                         case SHP_STENCIL:
  239.                             CHECKVERBOSE { fprintf(stdout, "stencil\n"); }
  240.                             break;
  241.  
  242.                         case SHP_AXIS:
  243.                             CHECKVERBOSE { fprintf(stdout, "axis\n"); }
  244.                             break;
  245.                     
  246.                         case SHP_FACETS:
  247.                             CHECKVERBOSE { fprintf(stdout, "facets\n"); }
  248.                             break;
  249.                 
  250.                         case SHP_SURFACE:
  251.                             CHECKVERBOSE { fprintf(stdout, "Surface\n"); }
  252.                             break;
  253.                 
  254.                         case SHP_GROUND:
  255.                             CHECKVERBOSE { fprintf(stdout, "Ground\n"); }
  256.                             break;
  257.                 
  258.                         default:
  259.                             CHECKTERSE { fprintf(stdout, "Unknown:  %d\n", 
  260.                                     shap.Shape); }
  261.                             break;
  262.                     }
  263.                     break;
  264.  
  265.                 case LMP_SUN:
  266.                     CHECKVERBOSE { fprintf(stdout, "Lamp (Sun)\n"); }
  267.                     break;
  268.                 
  269.                 case LMP_LAMP:
  270.                     CHECKVERBOSE { fprintf(stdout, "Lamp (Lamp)\n"); }
  271.                     break;
  272.                     
  273.                 default:
  274.                     break;
  275.             }        
  276.         }
  277.  
  278.         else if (chunk.name == MakeName("POSI")) 
  279.         {
  280.             found |= FND_POSI;
  281.             len -= ReadData(ifd, &posi, sizeof(POSI));
  282.             CHECKVERBOSE { fprintf(stdout, "\t\tPOSI:  <%f, %f, %f>\n", 
  283.                     posi.Position.X/65536.0, 
  284.                     posi.Position.Y/65536.0, posi.Position.Z/65536.0); }
  285.         }
  286.  
  287.         else if (chunk.name == MakeName("AXIS")) 
  288.         {
  289.             found |= FND_AXIS;
  290.             len -= ReadData(ifd, &axis, sizeof(AXIS));
  291.             CHECKVERBOSE { fprintf(stdout, "\t\tAXIS:  X = <%f, %f, %f>\n", 
  292.                     axis.XAxis.X/65536.0, axis.XAxis.Z/65536.0, 
  293.                     axis.XAxis.Y/65536.0); }
  294.             CHECKVERBOSE { fprintf(stdout, "\t\t       Y = <%f, %f, %f>\n", 
  295.                     axis.YAxis.X/65536.0, axis.YAxis.Z/65536.0, 
  296.                     axis.YAxis.Y/65536.0); }
  297.             CHECKVERBOSE { fprintf(stdout, "\t\t       Z = <%f, %f, %f>\n", 
  298.                     axis.ZAxis.X/65536.0, axis.ZAxis.Z/65536.0, 
  299.                     axis.ZAxis.Y/65536.0); }
  300.         }
  301.  
  302.         else if (chunk.name == MakeName("SIZE")) 
  303.         {
  304.             found |= FND_SIZE;
  305.             len -= ReadData(ifd, &size, sizeof(SIZE));
  306.             CHECKVERBOSE { fprintf(stdout, "\t\tSIZE:  <%f, %f, %f>\n", 
  307.                     size.Size.X/65536.0, size.Size.Y/65536.0, 
  308.                     size.Size.Z/65536.0); }
  309.         }
  310.  
  311.         else if (chunk.name == MakeName("PNTS")) 
  312.         {
  313.             if (pnts = (PNTS *)calloc(1, chunk.len)) 
  314.             {
  315.                 found |= FND_PNTS;
  316.                 len -= ReadData(ifd, &(pnts->PCount), 2);
  317.                 len -= ReadData(ifd, pnts->Points, chunk.len-2);
  318.                 CHECKVERBOSE { fprintf(stdout, "\t\tPNTS:  %d\n", pnts->PCount); }
  319.                 fprintf(ofh, "flushverts\n\n");
  320.                 for (i=0; i<pnts->PCount; i++)
  321.                     fprintf(ofh, "vertex T2AV_%d <%f, %f, %f>\n", i, -scalefactor*pnts->Points[i].X/65536.0,
  322.                             scalefactor*pnts->Points[i].Z/65536.0, scalefactor*pnts->Points[i].Y/65536.0);
  323.                 fprintf(ofh, "\n");
  324.             }
  325.             else
  326.                 fprintf(stdout, "PNTS found, no memory to load\n");
  327.         }
  328.  
  329.         else if (chunk.name == MakeName("EDGE")) 
  330.         {
  331.             if (edge = (EDGE *)calloc(1, chunk.len)) 
  332.             {
  333.                 found |= FND_EDGE;
  334.                 len -= ReadData(ifd, edge, chunk.len);
  335.                 CHECKVERBOSE { fprintf(stdout, "\t\tEDGE:  %d\n", edge->ECount); }
  336.             }
  337.             else
  338.                 fprintf(stdout, "EDGE found, no memory to load\n");
  339.         }
  340.  
  341.         else if (chunk.name == MakeName("FACE")) 
  342.         {
  343.             if (face = (FACE *)calloc(1, chunk.len)) 
  344.             {
  345.                 found |= FND_FACE;
  346.                 len -= ReadData(ifd, face, chunk.len);
  347.                 CHECKVERBOSE { fprintf(stdout, "\t\tFACE:  %d\n", face->TCount); }
  348.             }
  349.             else
  350.                 fprintf(stdout, "FACE found, no memory to load\n");
  351.         }
  352.  
  353.         else if (chunk.name == MakeName("COLR")) 
  354.         {
  355.             found |= FND_COLR;
  356.             len -= ReadData(ifd, &colr, sizeof(COLR));
  357.             CHECKVERBOSE { fprintf(stdout, "\t\tCOLR:  %d %d %d\n", 
  358.                     colr.col[0], colr.col[1], colr.col[2]); }
  359.         }
  360.  
  361.         else if (chunk.name == MakeName("REFL")) 
  362.         {
  363.             found |= FND_REFL;
  364.             len -= ReadData(ifd, &refl, sizeof(REFL));
  365.             CHECKVERBOSE { fprintf(stdout, "\t\tREFL:  %d %d %d\n", 
  366.                     refl.col[0], refl.col[1], refl.col[2]); }
  367.         }
  368.  
  369.         else if (chunk.name == MakeName("TRAN")) 
  370.         {
  371.             found |= FND_TRAN;
  372.             len -= ReadData(ifd, &tran, sizeof(TRAN));
  373.             CHECKVERBOSE { fprintf(stdout, "\t\tTRAN:  %d %d %d\n", 
  374.                     tran.col[0], tran.col[1], tran.col[2]); }
  375.         }
  376.  
  377.         else if (chunk.name == MakeName("SPC1"))
  378.         {
  379.             found |= FND_SPC1;
  380.             len -= ReadData(ifd, &tran, sizeof(TRAN));
  381.             CHECKVERBOSE fprintf(stdout, "\t\tSPC1:  %d %d %d\n",
  382.                     spc1.col[0], spc1.col[1], spc1.col[2]);
  383.         }
  384.  
  385.         else if (chunk.name == MakeName("CLST")) 
  386.         {
  387.             if (clst = (CLST *)calloc(1, chunk.len)) 
  388.             {
  389.                 found |= FND_CLST;
  390.                 len -= ReadData(ifd, clst, chunk.len);
  391.                 CHECKVERBOSE { fprintf(stdout, "\t\tCLST:  %d\n", clst->count); }
  392.             }
  393.             else
  394.                 fprintf(stdout, "CLST found, no memory to load\n");
  395.         }
  396.  
  397.         else if (chunk.name == MakeName("RLST")) 
  398.         {
  399.             if (rlst = (RLST *)calloc(1, chunk.len)) 
  400.             {
  401.                 found |= FND_RLST;
  402.                 len -= ReadData(ifd, rlst, chunk.len);
  403.                 CHECKVERBOSE { fprintf(stdout, "\t\tRLST:  %d\n", rlst->count); }
  404.             }
  405.             else
  406.                 fprintf(stdout, "RLST found, no memory to load\n");
  407.         }
  408.  
  409.         else if (chunk.name == MakeName("TLST")) 
  410.         {
  411.             if (tlst = (TLST *)calloc(1, chunk.len)) 
  412.             {
  413.                 found |= FND_TLST;
  414.                 len -= ReadData(ifd, tlst, chunk.len);
  415.                 CHECKVERBOSE { fprintf(stdout, "\t\tTLST:  %d\n", tlst->count); }
  416.             }
  417.             else
  418.                 fprintf(stdout, "TLST found, no memory to load\n");
  419.         }
  420.  
  421.         else if (chunk.name == MakeName("TPAR")) 
  422.         {
  423.             CHECKVERBOSE { fprintf(stdout, "\t\tTPAR:  found\n"); }
  424.             lseek(ifd, chunk.len, 1);
  425.             len -= chunk.len;
  426.         }
  427.  
  428.         else if (chunk.name == MakeName("SURF")) 
  429.         {
  430.             fprintf(stdout, "\t\tSURF:  found\n");
  431.             lseek(ifd, chunk.len, 1);
  432.             len -= chunk.len;
  433.         }
  434.  
  435.         else if (chunk.name == MakeName("MTTR")) 
  436.         {
  437.             found |= FND_MTTR;
  438.             len -= ReadData(ifd, &mttr, sizeof(MTTR));
  439.             switch (mttr.Type) 
  440.             {
  441.                 case RFR_AIR:
  442.                     CHECKVERBOSE { fprintf(stdout, "\t\tMTTR:  %f (Air)\n", VAL_AIR); }
  443.                     break;
  444.  
  445.                 case RFR_WATER:
  446.                     CHECKVERBOSE { fprintf(stdout, "\t\tMTTR:  %f (Water)\n", 
  447.                             VAL_WATER); }
  448.                     break;
  449.  
  450.                 case RFR_GLASS:
  451.                     CHECKVERBOSE { fprintf(stdout, "\t\tMTTR:  %f (Glass)\n", 
  452.                             VAL_GLASS); }
  453.                     break;
  454.  
  455.                 case RFR_CRYSTAL:
  456.                     CHECKVERBOSE { fprintf(stdout, "\t\tMTTR:  %f (Crystal)\n", 
  457.                             VAL_CRYSTAL); }
  458.                     break;
  459.  
  460.                 case RFR_CUSTOM:
  461.                     CHECKVERBOSE { fprintf(stdout, "\t\tMTTR:  %f (Custom)\n", 
  462.                             VAL_CUSTOM(mttr.Index)); }
  463.                     break;
  464.  
  465.                 default:
  466.                     CHECKTERSE { fprintf(stdout, "\t\tMTTR:  unknown type %d\n", 
  467.                             mttr.Type); }
  468.                     break;
  469.             }
  470.         }
  471.  
  472.         else if (chunk.name == MakeName("SPEC")) 
  473.         {
  474.             found |= FND_SPEC;
  475.             len -= ReadData(ifd, &spec, sizeof(SPEC));
  476.             fprintf(stdout, "\t\tSPEC:  Spec=%d, Hard=%d\n", 
  477.                     spec.Specularity, spec.Hardness);
  478.         }
  479.  
  480.         else if (chunk.name == MakeName("PRP0")) 
  481.         {
  482.             found |= FND_PRP0;
  483.             len -= ReadData(ifd, &prp, sizeof(PRP0));
  484.             CHECKVERBOSE { fprintf(stdout, "\t\tPRP0:  Blend = %d\n", prp.Props[PRP_BLEND]); }
  485.             CHECKVERBOSE { fprintf(stdout, "\t\t       Rough = %d\n", prp.Props[PRP_SMOOTH]); }
  486.             CHECKVERBOSE { fprintf(stdout, "\t\t       Shade = %s\n", 
  487.                     prp.Props[PRP_SHADE] ? "ON" : "OFF"); }
  488.             CHECKVERBOSE { fprintf(stdout, "\t\t       Phong = %s\n", 
  489.                     prp.Props[PRP_PHONG] ? "OFF" : "ON"); }
  490.             CHECKVERBOSE { fprintf(stdout, "\t\t       Glossy = %s\n", 
  491.                     prp.Props[PRP_GLOSSY] ? "ON" : "OFF"); }
  492.             CHECKVERBOSE { fprintf(stdout, "\t\t       Quick = %s\n", 
  493.                     prp.Props[PRP_QUICK] ? "ON" : "OFF"); }
  494.         }
  495.  
  496.         else if (chunk.name = MakeName("PRP1"))
  497.         {
  498.             found |= FND_PRP1;
  499.             len -= ReadData(ifd, &prp1, sizeof(PRP1));
  500.             CHECKVERBOSE fprintf(stdout, "\t\tPRP1:  Blend = %d\n", prp1.Props[PRP1_DITHER]);
  501.             CHECKVERBOSE fprintf(stdout, "\t\t       Hardness = %d\n", prp1.Props[PRP1_HARD]);
  502.             CHECKVERBOSE fprintf(stdout, "\t\t       Roughness = %d\n", prp1.Props[PRP1_ROUGH]);
  503.             CHECKVERBOSE fprintf(stdout, "\t\t       Shine = %d\n", prp1.Props[PRP1_SHINY]);
  504.             CHECKVERBOSE fprintf(stdout, "\t\t       Index = %d\n", prp1.Props[PRP1_INDEX]);
  505.             CHECKVERBOSE fprintf(stdout, "\t\t       Quick Draw = %s\n", (prp1.Props[PRP1_QUICK])?"ON":"OFF");
  506.             CHECKVERBOSE fprintf(stdout, "\t\t       Phong = %s\n", (prp1.Props[PRP1_PHONG])?"ON":"OFF");
  507.             CHECKVERBOSE fprintf(stdout, "\t\t       Genlock = %s\n", (prp1.Props[PRP1_GENLOCK])?"ON":"OFF");
  508.         }
  509.         else if (chunk.name == MakeName("INTS")) 
  510.         {
  511.             found |= FND_INTS;
  512.             len -= ReadData(ifd, &ints, sizeof(INTS));
  513.             CHECKVERBOSE { fprintf(stdout, "\t\tINTS:  %f\n", ints.Intensity/65536.0); }
  514.         }
  515.  
  516.         else if (chunk.name == MakeName("STRY")) 
  517.         {
  518.             CHECKVERBOSE { fprintf(stdout, "\t\tSTRY:  found\n"); }
  519.             lseek(ifd, chunk.len, 1);
  520.             len -= chunk.len;
  521.         }
  522.  
  523.         else 
  524.         {
  525.             CHECKTERSE { fprintf(stdout, "\t\t%.4s:  Found unknown chunk, skipping\n", &chunk.name); }
  526.             lseek(ifd, chunk.len, 1);
  527.             len -= chunk.len;
  528.         }
  529.     }
  530.  
  531.     if (whatami == SHP_AXIS) 
  532.     {
  533.         float mx[3]={-1e6, -1e6, -1e6}, mn[3]={1e6, 1e6, 1e6};
  534.  
  535.         degen = 0;
  536.         
  537.         if (pnts && edge && face)
  538.             CHECKTERSE { fprintf(stdout, "Dumping axis type object named \"%s\" with %d points, %d edges, and %d faces.\n",
  539.                     name.Name, pnts->PCount, edge->ECount, face->TCount); }
  540.  
  541.         fprintf(ofh, "/* --------- %s --------- */\n", name.Name);
  542.  
  543.         if (((found & FND_PRP0) && (!(prp.Props[PRP_SMOOTH]))) || ((found & FND_PRP1) && (!(prp1.Props[PRP1_PHONG]))))
  544.             fprintf(ofh, "smoothon\n");
  545.  
  546.         if ((found & (FND_PNTS | FND_EDGE | FND_FACE)) 
  547.                 != (FND_PNTS | FND_EDGE | FND_FACE))
  548.             { CHECKTERSE fprintf(stdout, "***\tError:  One of PNTS, EDGE, or FACE not found or allocated\n"); }
  549.         else 
  550.         {
  551.             for (i=0; i<pnts->PCount; i++) 
  552.             {
  553.                 pnts->Points[i].X *= -1.0;
  554.                 mx[0] = max(mx[0], pnts->Points[i].X/65536.0);
  555.                 mn[0] = min(mn[0], pnts->Points[i].X/65536.0);
  556.                 imx[0] = max(imx[0], pnts->Points[i].X/65536.0);
  557.                 imn[0] = min(imn[0], pnts->Points[i].X/65536.0);
  558.                 mx[1] = max(mx[1], pnts->Points[i].Y/65536.0);
  559.                 mn[1] = min(mn[1], pnts->Points[i].Y/65536.0);
  560.                 imx[1] = max(imx[1], pnts->Points[i].Y/65536.0);
  561.                 imn[1] = min(imn[1], pnts->Points[i].Y/65536.0);
  562.                 mx[2] = max(mx[2], pnts->Points[i].Z/65536.0);
  563.                 mn[2] = min(mn[2], pnts->Points[i].Z/65536.0);
  564.                 imx[2] = max(imx[2], pnts->Points[i].Z/65536.0);
  565.                 imn[2] = min(imn[2], pnts->Points[i].Z/65536.0);
  566.             }
  567.  
  568.             for (i=0; i<face->TCount; i++) 
  569.             {
  570.                 surf = MakeSurface(
  571.                     (found & FND_CLST)? clst->colors[i][0]: colr.col[0],
  572.                     (found & FND_CLST)? clst->colors[i][1]: colr.col[1],
  573.                     (found & FND_CLST)? clst->colors[i][2]: colr.col[2],
  574.                     (found & FND_RLST)? rlst->colors[i][0]: refl.col[0],
  575.                     (found & FND_RLST)? rlst->colors[i][1]: refl.col[1],
  576.                     (found & FND_RLST)? rlst->colors[i][2]: refl.col[2],
  577.                     (found & FND_TLST)? tlst->colors[i][0]: tran.col[0],
  578.                     (found & FND_TLST)? tlst->colors[i][1]: tran.col[1],
  579.                     (found & FND_TLST)? tlst->colors[i][2]: tran.col[2],
  580.                     (found & FND_SPEC) ? spec.Hardness : 0,
  581.                     (found & FND_SPEC) ? spec.Specularity : 0,
  582.                     (found & FND_MTTR) ? mttr.Index : 0);
  583.                     
  584.                 p1 = edge->Edges[face->Connects[i][0]][0];
  585.                 p2 = edge->Edges[face->Connects[i][0]][1];
  586.                 p3 = edge->Edges[face->Connects[i][1]][0];
  587.                 p3 = ((p1 == p3) || (p2 == p3)) ? 
  588.                         edge->Edges[face->Connects[i][1]][1] : p3;
  589.  
  590.                 if ((pnts->Points[p1].X == pnts->Points[p2].X) 
  591.                         && (pnts->Points[p1].Y == pnts->Points[p2].Y) 
  592.                         && (pnts->Points[p1].Z == pnts->Points[p2].Z))
  593.                     degen++;
  594.                 else if ((pnts->Points[p1].X == pnts->Points[p3].X) 
  595.                         && (pnts->Points[p1].Y == pnts->Points[p3].Y) 
  596.                         && (pnts->Points[p1].Z == pnts->Points[p3].Z))
  597.                     degen++;
  598.                 else if ((pnts->Points[p2].X == pnts->Points[p3].X) 
  599.                         && (pnts->Points[p2].Y == pnts->Points[p3].Y) 
  600.                         && (pnts->Points[p2].Z == pnts->Points[p3].Z))
  601.                     degen++;
  602.                 else 
  603.                 {
  604.                     fprintf(ofh, "triangle {\n");
  605.                     fprintf(ofh, "\tp1\tT2AV_%d\n", p1);
  606.                     fprintf(ofh, "\tp2\tT2AV_%d\n", p2);
  607.                     fprintf(ofh, "\tp3\tT2AV_%d\n", p3);
  608.                     fprintf(ofh, "\tpatt\t%s\n", surf->name);
  609.                     fprintf(ofh, "}\n\n");
  610.                 }
  611.             }
  612.             if (degen) 
  613.                 CHECKTERSE { fprintf(stdout, "%d of %d triangle degenerative\n", degen, face->TCount); }
  614.             CHECKTERSE { fprintf(stdout, "Axis bounds: <%f, %f, %f> - <%f, %f, %f>\n\n",
  615.                      mn[0], mn[2], mn[1], mx[0], mx[2], mx[1]); }
  616.         }
  617.         if (((found & FND_PRP0) && (!(prp.Props[PRP_SMOOTH]))) || ((found & FND_PRP1) && (!(prp1.Props[PRP1_PHONG]))))
  618.             fprintf(ofh, "smoothoff\n");
  619.  
  620.     }
  621.  
  622.     if (found & FND_PNTS)
  623.         free(pnts);
  624.     if (found & FND_EDGE)
  625.         free(edge);
  626.     if (found & FND_FACE)
  627.         free(face);
  628.     if (found & FND_TLST)
  629.         free(tlst);
  630.     if (found & FND_RLST)
  631.         free(rlst);
  632.     if (found & FND_CLST)
  633.         free(clst);
  634. }
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641. void GetObjChunk(int ifd, int len)
  642. {
  643.     Chunk    chunk;
  644.     
  645.     while (len) {
  646.         len -= read(ifd, &chunk, sizeof(Chunk));
  647.  
  648.         if (chunk.name == MakeName("EXTR")) {
  649.             CHECKVERBOSE { fprintf(stdout, "\tEXTR:  found\n"); }
  650.             lseek(ifd, chunk.len, 1);
  651.             len -= chunk.len;
  652.         }
  653.         
  654.         else if (chunk.name == MakeName("TOBJ")) {
  655.             CHECKVERBOSE { fprintf(stdout, "\tTOBJ:\n\n"); }
  656.             lseek(ifd, chunk.len, 1);
  657.             len -= chunk.len;
  658.         }
  659.         
  660.         else if (chunk.name == MakeName("DESC")) {
  661.             CHECKVERBOSE { fprintf(stdout, "\tDESC:\n"); }
  662.             GetDescChunk(ifd, chunk.len);
  663.             len -= chunk.len;
  664.         }
  665.         
  666.         else {
  667.             CHECKTERSE { fprintf(stdout, "\t%.4s:  Found unknown chunk\n", &chunk.name); }
  668.             lseek(ifd, chunk.len, 1);
  669.             len -= chunk.len;
  670.         }
  671.     }
  672. }
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679. void GetInfoChunk(int ifd, int len)
  680. {
  681.     Chunk    chunk;
  682.     
  683.     while (len) {
  684.         len -= read(ifd, &chunk, sizeof(Chunk));
  685.  
  686.         if (chunk.name == MakeName("BRSH")) {
  687.             BRSH brsh;
  688.             len -= ReadData(ifd, &brsh, sizeof(BRSH));
  689.             CHECKVERBOSE { fprintf(stdout, "\tBRSH:  #%d = %s\n", brsh.Number, brsh.Filename); }
  690.         }
  691.         
  692.         else if (chunk.name == MakeName("STNC")) {
  693.             STNC stnc;
  694.             len -= ReadData(ifd, &stnc, sizeof(STNC));
  695.             CHECKVERBOSE { fprintf(stdout, "\tSTNC:  #%d = %s\n", stnc.Number, stnc.Filename); }
  696.         }
  697.         
  698.         else if (chunk.name == MakeName("TXTR")) {
  699.             TXTR txtr;
  700.             len -= ReadData(ifd, &txtr, sizeof(TXTR));
  701.             CHECKVERBOSE { fprintf(stdout, "\tTXTR:  #%d = %s\n", txtr.Number, txtr.Filename); }
  702.         }
  703.         
  704.         else if (chunk.name == MakeName("OBSV")) {
  705.             OBSV obsv;
  706.             len -= ReadData(ifd, &obsv, sizeof(OBSV));
  707.             CHECKTERSE { fprintf(stdout, "\tOBSV:  Location = <%f, %f, %f>\n", obsv.Camera.X/65536.0, obsv.Camera.Y/65536, obsv.Camera.Z/65536.0); }
  708.             CHECKTERSE { fprintf(stdout, "\t       Rotate = <%f, %f, %f>\n", obsv.Rotate.X/65536.0, obsv.Rotate.Y/65536, obsv.Rotate.Z/65536.0); }
  709.             CHECKTERSE { fprintf(stdout, "\t       Focal Len. = %f\n", obsv.Focal/65536.0); }
  710.         }
  711.         
  712.         else if (chunk.name == MakeName("OTRK")) {
  713.             OTRK otrk;
  714.             len -= ReadData(ifd, &otrk, sizeof(OTRK));
  715.             CHECKVERBOSE { fprintf(stdout, "\tOTRK:  %s\n", otrk.Trackname); }
  716.         }
  717.         
  718.         else if (chunk.name == MakeName("OSTR")) {
  719.             CHECKVERBOSE { fprintf(stdout, "\tOSTR:  found\n"); }
  720.             lseek(ifd, chunk.len, 1);
  721.             len -= chunk.len;
  722.         }
  723.         
  724.         else if (chunk.name == MakeName("FADE")) {
  725.             CHECKVERBOSE { fprintf(stdout, "\tFADE:  found\n"); }
  726.             lseek(ifd, chunk.len, 1);
  727.             len -= chunk.len;
  728.         }
  729.         
  730.         else if (chunk.name == MakeName("SKYC")) {
  731.             CHECKVERBOSE { fprintf(stdout, "\tSKYC:  found\n"); }
  732.             lseek(ifd, chunk.len, 1);
  733.             len -= chunk.len;
  734.         }
  735.         
  736.         else if (chunk.name == MakeName("AMBI")) {
  737.             CHECKVERBOSE { fprintf(stdout, "\tAMBI:  found\n"); }
  738.             lseek(ifd, chunk.len, 1);
  739.             len -= chunk.len;
  740.         }
  741.         
  742.         else if (chunk.name == MakeName("GLB0")) {
  743.             CHECKVERBOSE { fprintf(stdout, "\tGLB0:  found\n"); }
  744.             lseek(ifd, chunk.len, 1);
  745.             len -= chunk.len;
  746.         }
  747.         
  748.         else {
  749.             CHECKTERSE { fprintf(stdout, "\t%.4s:  Found unknown chunk\n", &chunk.name); }
  750.             lseek(ifd, chunk.len, 1);
  751.             len -= chunk.len;
  752.         }
  753.     }
  754. }
  755.  
  756.  
  757.  
  758.  
  759.  
  760. #define PRINTUSAGE fprintf(stderr,"%s [-q|-t|-v] [-o] [-s scalefactor] infile outfile\n", argv[0]);
  761.  
  762.  
  763. void parsecl(int argc, char **argv)
  764. {
  765.     int    i;
  766.  
  767.     for (i=1; i<argc; i++)
  768.     {
  769.         if (argv[i][0] != '-')
  770.         {
  771.             fprintf(stderr, "%s:  malformed option %s\n", argv[0], argv[i]);
  772.             PRINTUSAGE;
  773.             exit(20);
  774.         }
  775.  
  776.         switch (argv[i][1])
  777.         {
  778.             case 'v':
  779.                 printmode = VERBOSE;
  780.                 break;
  781.  
  782.             case 't':
  783.                 printmode = TERSE;
  784.                 break;
  785.  
  786.             case 'q':
  787.                 printmode = QUIET;
  788.                 break;
  789.  
  790.             case 'o':
  791.                 flags |= FL_OBJECTS;
  792.                 break;
  793.  
  794.             case 's':
  795.                 i++;
  796.                 scalefactor = atof(argv[i]);
  797.                 break;
  798.  
  799.             default:
  800.                 fprintf(stderr, "%s: illegal option %s\n", argv[0], argv[i]);
  801.                 PRINTUSAGE;
  802.                 exit(20);
  803.         }
  804.     }
  805. }
  806.  
  807.  
  808.  
  809.  
  810. void main(int argc, char **argv)
  811. {
  812.     int        ifd=-1;
  813.     Form    form;
  814.     Chunk    chunk;
  815.     int        len;
  816.     
  817.     if ((argc < 3) || (argc > 6)) {
  818.         PRINTUSAGE;
  819.         goto cleanup;
  820.     }
  821.  
  822.     parsecl(argc-2, argv);
  823.  
  824.     if ((ifd = open(argv[argc==4?2:1], O_RDONLY)) == -1) {
  825.         fprintf(stdout, "turbo2arrt:  could not open input file %s\n", argv[argc==4?2:1]);
  826.         goto cleanup;
  827.     }
  828.     
  829.     if (!(ofh = fopen(argv[argc==4?3:2], "w"))) {
  830.         fprintf(stdout, "turbo2arrt:  could not open output file %s\n", argv[argc==4?3:2]);
  831.         goto cleanup;
  832.     }
  833.  
  834.     filename = argv[argc==4?2:1];
  835.  
  836.     read(ifd, &form, sizeof(Form));
  837.     if ((form.form != MakeName("FORM")) || (form.type != MakeName("TDDD"))) {
  838.         fprintf(stdout, "turbo2arrt:  %s is not proper file type\n", argv[1]);
  839.         goto cleanup;
  840.     }
  841.     
  842.     len = read(ifd, &chunk, sizeof(Chunk));
  843.     while (len) {
  844.         if (chunk.name == MakeName("INFO")) {
  845.             CHECKVERBOSE { fprintf(stdout, "INFO:\n"); }
  846.             GetInfoChunk(ifd, chunk.len);
  847.             CHECKVERBOSE { fprintf(stdout, "\n\n"); }
  848.         }
  849.         
  850.         else if (chunk.name == MakeName("OBJ ")) {
  851.             CHECKVERBOSE { fprintf(stdout, "OBJ :\n"); }
  852.             GetObjChunk(ifd, chunk.len);
  853.             CHECKVERBOSE { fprintf(stdout, "\n"); }
  854.         }
  855.  
  856.         else {
  857.             CHECKTERSE { fprintf(stdout, "%.4s:  Found unknown chunk\n\n\n", &chunk.name); }
  858.             lseek(ifd, chunk.len, 1);
  859.         }
  860.  
  861.         len = read(ifd, &chunk, sizeof(Chunk));
  862.     }
  863.  
  864.     CHECKTERSE { fprintf(stdout, "***\n\tObject Bounds: <%f, %f, %f> - <%f, %f, %f>\n", imn[0], imn[2], imn[1], imx[0], imx[2], imx[1]); }
  865.  
  866. cleanup:
  867.  
  868.     if (ifd != -1)
  869.         close(ifd);
  870.     if (ofh)
  871.         fclose(ofh);
  872. }
  873.